<?php

declare(strict_types=1);

namespace Zms\AdminElementPlus\FormCreate;

use Zms\AdminElementPlus\FormCreate\FormItem\FormItemAbstract;

/**
 * 表单生成器
 * @link http://www.form-create.com/v3/element-ui/global.html
 * Class Form
 */
class Form
{
    const SIZE_SMALL = 'small';//小
    const SIZE_MEDIUM = 'medium';//中
    const SIZE_LARGE = 'large';//大

    private string $_title = '编辑信息';
    private string $_action = '';
    private string $_method = 'POST';

    /**
     * 表单规则
     * @var array
     */
    private array $_rule = [];


    /**
     * 表单规则
     * @var array
     */
    private array $_value = [];


    private array $_option = [
        'form' => [
            'inline' => false,
            'labelPosition' => 'right',
            'labelWidth' => '100px',
            'disabled' => false
        ]
    ];


    /**
     * 创建表单实例
     * @param string $title
     * @param string $action
     * @param string $method
     * @return Form
     */
    public static function create(string $title = '', string $action = '', string $method = 'POST'): Form
    {
        $form = new self();
        if ($title) $form->setTitle($title);
        if ($action) $form->setAction($action);
        if ($method) $form->setMethod($method);
        return $form;
    }


    /**
     * 设置标题
     * @param string $title
     * @return  $this
     */
    public function setTitle(string $title): Form
    {

        $this->_title = $title;
        return $this;
    }


    /**
     * 设置请求地址
     * @param string $action
     * @return  $this
     */
    public function setAction(string $action): Form
    {

        $this->_action = $action;
        return $this;
    }


    /**
     * 设置请求方式
     * @param string $method
     * @return  $this
     */
    public function setMethod(string $method): Form
    {

        $this->_method = $method;
        return $this;
    }


    /**
     * 追加表单
     */
    public function appendRule(FormItemAbstract $rule): void
    {
        $this->_rule[] = $rule->toArray();
    }

    /**
     * 转数组
     */
    public function toArray(): array
    {
        if (count($this->_value) > 0) {
            foreach ($this->_rule as &$item) {
                if (isset($this->_value[$item['field']])) {
                    $item['value'] = $this->_value[$item['field']];
                }
            }
        }
        return [
            'title' => $this->_title,
            'action' => $this->_action,
            'method' => $this->_method,
            'rule' => $this->_rule,
            'option' => $this->_option,
        ];
    }

    /**
     * 设置规则
     */
    public function setRules(array $rules, array $allow = []): Form
    {
        $_rule = [];
        /**
         * @var FormItemAbstract $item
         */
        foreach ($rules as $item) {
            if (count($allow) === 0 || in_array($item->getField(), $allow)) {
                $_rule[] = $item->toArray();
            }
        }
        $this->_rule = $_rule;
        return $this;
    }

    /**
     * 设置值
     */
    public function setValues(array $_value): Form
    {
        $this->_value = $_value;
        return $this;
    }


    /**
     * @param string $size small|default
     * @return $this
     */
    public function setSize(string $size): Form
    {
        $this->_option['form']['size'] = $size;
        return $this;
    }

    /**
     * 设置额外配置
     * @param array $option
     * @return Form
     */
    public function setOption(array $option): Form
    {
        $this->_option = $option;
        return $this;
    }

    /**
     * 是否展示为行内表单
     * @param bool $inline
     * @return Form
     */
    public function setOptionFormInline(bool $inline): Form
    {
        $this->_option['inline'] = $inline;
        return $this;
    }

    /**
     * 标签显示的位置
     * @param string|int $labelPosition
     * @return Form
     */
    public function labelPosition(string|int $labelPosition): Form
    {
        $this->_option['form']['labelPosition'] = $labelPosition;
        return $this;
    }

    /**
     * 标签宽度
     * @param string|int $labelWidth
     * @return Form
     */
    public function labelWidth(string|int $labelWidth): Form
    {
        $this->_option['form']['labelWidth'] = $labelWidth;
        return $this;
    }

    /**
     * 表单禁用
     * @param bool $disabled
     * @return Form
     */
    public function disabled(bool $disabled): Form
    {
        $this->_option['form']['disabled'] = $disabled;
        return $this;
    }

    /**
     * 表单大小
     * @param bool $size
     * @return Form
     */
    public function size(bool $size): Form
    {
        $this->_option['form']['size'] = $size;
        return $this;
    }

}